iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0
自我挑戰組

初階面試常見題目彙整系列 第 18

初階面試常見題目回答-策略模式-鐵人賽第十八日

  • 分享至 

  • xImage
  •  

策略模式(Strategy Pattern)是一種行為型設計模式,它由以下幾個主要元素組成:

上下文(Context):上下文是包含一個策略的類別,它擁有一個策略介面的參考,並通常具有一個方法用於設定策略,以及其他方法用於執行策略。

策略介面(Strategy Interface):策略模式定義了一個策略介面,它包含一組方法,這些方法是不同策略實現必須實現的。

具體策略(Concrete Strategies):具體策略是實現策略介面的具體類別,每個具體策略都實現了策略介面中的方法,以提供不同的策略實現。

上下文使用策略(Context Using Strategy):上下文類別使用策略介面的參考來設置和切換不同的具體策略。

簡而言之,策略模式主要用於在運行時選擇不同的算法,

在一開始有說過行為型模式(Behavioral Patterns),
是有點像是介面的,主要是在不同的object之間的協作,
更偏向各個角色之間的相互作用,
那麼有說是if...else和策略模式的實現方式。
說到這就會想起第十四日所說的簡單工廠模式。

筆者在之前是用字典,
但其實用if...else也可以,
也是非常常用的一種形式。

那麼兩者最大的不同,
就是一個已知,
一個未知。

再施展一個策略的時候,
不可能會施展一個我不知道的策略,
這樣想想到奇怪,
帶來這邊,
也很明確的就是會知道有這個策略,
而我想使用這個策略。

而這就代表一件事情,
Client是知道內部有什麼策略的,
而這就是與簡單工廠最大的不同。

舉個例子,
在開車的時候常常會有切換檔位,
簡單分為爬坡時的低檔、加速的高檔跟後退的倒檔。

使用者就會根據需要的狀況去切換檔位。


public interface ITransmissionStrategy
{
    string Shift();
}

public class LowGearStrategy : ITransmissionStrategy
{
    public string Shift()
    {
        return "低檔:適合在爬坡使用。";
    }
}

public class HighGearStrategy : ITransmissionStrategy
{
    public string Shift()
    {
        return "高檔:提供更高的速度。";
    }
}

public class ReverseGearStrategy : ITransmissionStrategy
{
    public string Shift()
    {
        return "倒檔:用於後退行駛。";
    }
}

public class Car
{
    private ITransmissionStrategy _transmissionStrategy;

    public Car(ITransmissionStrategy transmissionStrategy)
    {
        _transmissionStrategy = transmissionStrategy;
    }

    public void SetTransmissionStrategy(ITransmissionStrategy transmissionStrategy)
    {
        _transmissionStrategy = transmissionStrategy;
    }

    public string Shift()
    {
        return _transmissionStrategy.Shift();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Car car = new Car(new LowGearStrategy());

        // 使用低檔策略
        string lowGearShift = car.Shift();
        Console.WriteLine(lowGearShift);

        // 切換到高檔策略
        car.SetTransmissionStrategy(new HighGearStrategy());
        string highGearShift = car.Shift();
        Console.WriteLine(highGearShift);

        // 切換到倒檔策略
        car.SetTransmissionStrategy(new ReverseGearStrategy());
        string reverseGearShift = car.Shift();
        Console.WriteLine(reverseGearShift);
    }
}

那麼第十三天筆者有提過,行為型模式(Behavioral Patterns)角色之間的相互作用,
那麼是不是代表著一定要一個object以上才能進行呢?
從以上的介紹能明顯發現,
其實可以不用,
就如同這裡只有一個car,
依然可以自然得切換檔位。

上下文(Context):上下文是包含一個策略的類別,它擁有一個策略介面的參考。
在這裡很明確的是car這個class,而裡面透過SetTransmissionStrategy 設定策略。

策略介面(Strategy Interface):在這邊有著通用interface,也就是ITransmissionStrategy ,
而這個就是用來新增修改策略用的,而不會去影響到Context,也就是開發封閉原則(OCP)的延伸。

具體策略(Concrete Strategies):
也就是實際實現的程式,低檔高檔與倒檔,
LowGearStrategy、HighGearStrategy與ReverseGearStrategy他們去實現了interface,
提供了不同的實際策略。

上下文使用策略(Context Using Strategy):
也就是car這個Class是怎麼使用策略的,
以這個例子而言,
是透過Shift這個function,
來執行當前需要什麼策略。


上一篇
初階面試常見題目回答-建造者模式-鐵人賽第十七日
下一篇
初階面試常見題目回答-單例模式-鐵人賽第十九日
系列文
初階面試常見題目彙整30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言